package com.geek.week01;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class HelloClassLoader extends ClassLoader {

	public static void main(String[] args){
		try {
			Object obj = new HelloClassLoader().findClass("Hello").newInstance();
			Method method = obj.getClass().getDeclaredMethod("hello", null);
			method.invoke(obj, null);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		String path = HelloClassLoader.class.getClassLoader().getResource("Hello.xlass").getPath();
		try {
			byte[] sourceContent = toByteArray(path);
			byte[] realBytes = getRealByte(sourceContent);
			return defineClass(name, realBytes, 0, realBytes.length);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取真正的字节数组
	 * @param content
	 * @return
	 */
	private static byte[] getRealByte(byte[] content) {
		if (null == content || content.length == 0) {
			return null;
		}
		byte[] real = new byte[content.length];
		for (int i = 0; i < content.length; i++) {
			real[i] = (byte) (255 - content[i]);
		}
		return real;
	}


	/**
	 * 把文件转换为字节数组
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	public static byte[] toByteArray(String filename) throws IOException {

		File f = new File(filename);
		if (!f.exists()) {
			throw new FileNotFoundException(filename);
		}

		ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
		BufferedInputStream in = null;
		try {
			in = new BufferedInputStream(new FileInputStream(f));
			int buf_size = 1024;
			byte[] buffer = new byte[buf_size];
			int len = 0;
			while (-1 != (len = in.read(buffer, 0, buf_size))) {
				bos.write(buffer, 0, len);
			}
			return bos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			bos.close();
		}
	}

}
